<script>
    // 动态编译程序集的卸载

            /*
                    对于动态编译生成的程序集，卸载方式与普通程序集类似，

                    但需要特别注意 "上下文隔离" 和 "资源释放"。动态编译的程序集通常是临时的，更需要妥善卸载以避免内存泄露。

                    以下是针对动态编译程序集的卸载方案 ：
            */

            /*
                一、  .net Framework 中的实现( 使用AppDomain)

                                        using System;
                                        using System.CodeDom.Compiler;
                                        using System.Reflection;
                                        using Microsoft.CSharp;

                                        public class DynamicAssemblyLoader : MarshalByRefObject
                                        {
                                            // 在独立应用域中编译并加载代码
                                            public void CompileAndExecute(string code)
                                            {
                                                // 动态编译代码
                                                using (CSharpCodeProvider provider = new CSharpCodeProvider())
                                                {
                                                    CompilerParameters parameters = new CompilerParameters();
                                                    parameters.GenerateInMemory = true; // 内存中生成程序集
                                                    parameters.ReferencedAssemblies.Add("System.dll");

                                                    CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
                                                    
                                                    if (results.Errors.HasErrors)
                                                    {
                                                        throw new Exception("编译错误: " + string.Join(", ", 
                                                            results.Errors.Cast<CompilerError>().Select(e => e.ErrorText)));
                                                    }

                                                    // 执行动态程序集中的方法
                                                    Assembly assembly = results.CompiledAssembly;
                                                    Type type = assembly.GetType("DynamicCode.MyClass");
                                                    object instance = Activator.CreateInstance(type);
                                                    type.GetMethod("Execute").Invoke(instance, null);
                                                }
                                            }
                                        }

                                        // 使用示例
                                        class Program
                                        {
                                            static void Main()
                                            {
                                                // 动态代码示例
                                                string dynamicCode = @"
                                                    namespace DynamicCode
                                                    {
                                                        public class MyClass
                                                        {
                                                            public void Execute()
                                                            {
                                                                System.Console.WriteLine(""动态代码执行中..."");
                                                            }
                                                        }
                                                    }";

                                                // 创建独立应用域
                                                AppDomainSetup setup = new AppDomainSetup();
                                                setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                                                AppDomain tempDomain = AppDomain.CreateDomain("DynamicAssemblyDomain", null, setup);

                                                try
                                                {
                                                    // 在独立域中加载并执行动态程序集
                                                    DynamicAssemblyLoader loader = (DynamicAssemblyLoader)tempDomain.CreateInstanceAndUnwrap(
                                                        typeof(DynamicAssemblyLoader).Assembly.FullName,
                                                        typeof(DynamicAssemblyLoader).FullName);
                                                    
                                                    loader.CompileAndExecute(dynamicCode);
                                                }
                                                finally
                                                {
                                                    // 卸载应用域，释放动态程序集
                                                    AppDomain.Unload(tempDomain);
                                                    Console.WriteLine("动态程序集已卸载");
                                                }
                                            }
                                        }
            */


            /*
                二、.NET Core /.Net5+ 中的实现 (使用AssemblyLoadContext)

                            在现代 .net 中， AssemblyLoadContext 是更推荐的方式，尤其适合动态编译场景：

                                    using System;
                                    using System.Reflection;
                                    using System.Runtime.Loader;
                                    using Microsoft.CodeAnalysis;
                                    using Microsoft.CodeAnalysis.CSharp;
                                    using System.Linq;
                                    using System.IO;

                                    public class DynamicAssemblyLoadContext : AssemblyLoadContext
                                    {
                                        public DynamicAssemblyLoadContext() : base(isCollectible: true) { } // 可回收

                                        protected override Assembly? Load(AssemblyName assemblyName)
                                        {
                                            // 仅加载我们动态生成的程序集
                                            return null;
                                        }
                                    }

                                    public class DynamicCompiler
                                    {
                                        public void CompileAndUnload(string code)
                                        {
                                            // 1. 编译代码生成程序集
                                            var syntaxTree = CSharpSyntaxTree.ParseText(code);
                                            var references = new MetadataReference[]
                                            {
                                                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                                                MetadataReference.CreateFromFile(typeof(Console).Assembly.Location)
                                            };

                                            var compilation = CSharpCompilation.Create(
                                                "DynamicAssembly",
                                                new[] { syntaxTree },
                                                references,
                                                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

                                            // 2. 在内存中生成程序集
                                            using var ms = new MemoryStream();
                                            var result = compilation.Emit(ms);
                                            if (!result.Success)
                                            {
                                                throw new Exception("编译失败: " + string.Join(", ", 
                                                    result.Diagnostics.Where(d => d.IsError).Select(d => d.GetMessage())));
                                            }

                                            ms.Position = 0;

                                            // 3. 使用自定义ALC加载程序集
                                            var alc = new DynamicAssemblyLoadContext();
                                            var assembly = alc.LoadFromStream(ms);

                                            // 4. 执行动态代码
                                            var type = assembly.GetType("DynamicCode.MyClass");
                                            var instance = Activator.CreateInstance(type);
                                            type.GetMethod("Execute").Invoke(instance, null);

                                            // 5. 准备卸载
                                            assembly = null;
                                            type = null;
                                            instance = null;

                                            // 6. 触发垃圾回收以确保卸载
                                            GC.Collect();
                                            GC.WaitForPendingFinalizers();
                                            alc.Unload(); // 卸载程序集
                                            Console.WriteLine("动态程序集已卸载");
                                        }
                                    }

                                    // 使用示例
                                    class Program
                                    {
                                        static void Main()
                                        {
                                            string code = @"
                                                namespace DynamicCode
                                                {
                                                    public class MyClass
                                                    {
                                                        public void Execute()
                                                        {
                                                            System.Console.WriteLine(""动态代码执行中..."");
                                                        }
                                                    }
                                                }";

                                            var compiler = new DynamicCompiler();
                                            compiler.CompileAndUnload(code);
                                        }
                                    }
            */

            /*
                    三、关键事项 (针对动态编译场景)

                                1、内存管理

                                         ①、冬天编译的程序集更容易造成内存泄露，务必确保所有引用都被释放

                                         ②、卸载钱显式设置相关对象为null,并触发垃圾回收

                                2、编译选项

                                         ①、避免将动态程序集生成到磁盘 (使用内存流)

                                         ②、确保编译时只引用必要的程序集

                                3、跨域通信：

                                         动态程序集中的 "类型" 不能跨越应用域直接使用，需要通过 "接口或MarshalByRefObject 

                                4、调试建议：

                                         ①、使用 GC.Collect() 强制垃圾回收帮助测试卸载是否成功

                                         ②、可通过内存分析工具 (如 Visual Studio 的诊断工具)验证程序集是否被释放。

            */


           /*
                 总结：

                        这种方式能有效管理冬天编译程序集的生命周期，特别适合插件系统、脚本执行等需要动态加载和卸载代码的场景。
           */
</script>